package com.sgcc.nfc.lock.presentation.map

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sgcc.nfc.lock.core.network.NetworkResult
import com.sgcc.nfc.lock.domain.model.MapFilter
import com.sgcc.nfc.lock.domain.model.MapPoint
import com.sgcc.nfc.lock.domain.model.MapStats
import com.sgcc.nfc.lock.domain.model.Region
import com.sgcc.nfc.lock.domain.model.RoomStatus
import com.sgcc.nfc.lock.domain.usecase.GetMapRoomsUseCase
import com.sgcc.nfc.lock.domain.usecase.GetRegionTreeUseCase
import com.sgcc.nfc.lock.domain.model.isClosed
import com.sgcc.nfc.lock.domain.model.isIdle
import com.sgcc.nfc.lock.domain.model.isProblematic
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.launch

@HiltViewModel
class MapViewModel @Inject constructor(
    private val getMapRoomsUseCase: GetMapRoomsUseCase,
    private val getRegionTreeUseCase: GetRegionTreeUseCase
) : ViewModel() {

    private val _uiState = MutableLiveData(MapUiState())
    val uiState: LiveData<MapUiState> = _uiState

    init {
        println("MapViewModel: 初始化")
        loadRegions()
        loadPoints()
    }

    fun loadPoints(filter: MapFilter = _uiState.value?.filter ?: MapFilter()) {
        println("MapViewModel: 加载地图点数据 - filter=$filter")
        viewModelScope.launch {
            _uiState.update { 
                it.copy(
                    isLoading = true,
                    filter = filter,
                    error = null
                )
            }
            
            try {
                val result = getMapRoomsUseCase(
                    regionId = filter.regionId,
                    status = filter.status?.let { statusToCode(it) }
                )
                
                when (result) {
                    is NetworkResult.Success -> {
                        val points = result.data
                        _uiState.update { 
                            it.copy(
                                isLoading = false,
                                points = points,
                                stats = computeStats(points),
                                error = null
                            )
                        }
                    }
                    is NetworkResult.Error -> {
                        _uiState.update { 
                            it.copy(
                                isLoading = false,
                                error = result.message ?: "加载失败"
                            )
                        }
                    }
                    NetworkResult.Loading -> {
                        // 保持loading状态
                    }
                }
            } catch (e: Exception) {
                _uiState.update { 
                    it.copy(
                        isLoading = false,
                        error = e.message ?: "未知错误"
                    )
                }
            }
        }
    }

    fun applyFilter(filter: MapFilter) {
        println("MapViewModel: 应用过滤器 - filter=$filter")
        loadPoints(filter)
    }

    private fun loadRegions() {
        println("MapViewModel: 加载区域数据")
        viewModelScope.launch {
            try {
                val result = getRegionTreeUseCase()
                when (result) {
                    is NetworkResult.Success -> {
                        _uiState.update { it.copy(regions = result.data) }
                    }
                    is NetworkResult.Error -> {
                        println("MapViewModel: 加载区域失败 - ${result.message}")
                    }
                    NetworkResult.Loading -> {
                        // 忽略loading状态
                    }
                }
            } catch (e: Exception) {
                println("MapViewModel: 加载区域异常 - ${e.message}")
            }
        }
    }

    private fun computeStats(points: List<MapPoint>): MapStats {
        val total = points.size
        val closed = points.count { it.isClosed() }
        val open = points.count { it.isProblematic() }
        val idle = points.count { it.isIdle() }
        return MapStats(total, closed, open, idle)
    }

    private fun statusToCode(status: RoomStatus): Int? = when (status) {
        RoomStatus.NORMAL -> 0
        RoomStatus.IN_USE -> 1
        RoomStatus.ALERT -> 2
        RoomStatus.UNKNOWN -> null
    }

    private inline fun MutableLiveData<MapUiState>.update(transform: (MapUiState) -> MapUiState) {
        val current = value ?: MapUiState()
        value = transform(current)
    }
}
